<template>
    <Layout class="detail-container" v-loading="is_loading">
        <template #main>
            <div class="container" ref="container">
                <BlogDetail :data="data" v-if="data" ref="detail" />
                <MessageArea
                    v-if="data && comment_data"
                    title="评论列表"
                    ref="message"
                    :subTitle="comment_data.total + ''"
                    :list="comment_data.rows"
                    :isListLoading="is_list_loading"
                    :text="text"
                    @submit="handle_submit"
                />
            </div>
        </template>
        <template #right>
            <h2>目录</h2>
            <BlogToc
                :list="data.toc"
                :active_anchor="active_anchor"
                v-if="data"
            />
        </template>
    </Layout>
</template>

<script>
import { request, debounce, title_manager } from "@/utils"
import Layout from "@/components/Layout"
import BlogDetail from "./components/BlogDetail"
import BlogToc from "./components/BlogToc"
import MessageArea from "@/components/MessageArea"
import { back_top } from "@/mixins"

export default {
    mounted() {
        request.get("/api/blog/" + this.blog_id).then((resp) => {
            this.data = resp
            title_manager.set_router_title(resp.title)
            this.is_loading = false
        })
        request.get("/api/comment?page=" + this.page).then((resp) => {
            this.comment_data = resp
            this.is_list_loading = false
        })
        // 防抖，延时 50 毫秒
        this.handle_anchor = debounce(this.get_anchor, 100)
        // 监听滚动事件，执行处理函数
        this.$refs.container.addEventListener("scroll", this.handle_anchor)
        this.$refs.container.addEventListener("scroll", this.handle_scroll)
    },
    beforeDestroy() {
        // 在销毁前移除 dom 事件，销毁后就没有 dom 对象了
        this.$refs.container.removeEventListener("scroll", this.handle_anchor)
        this.$refs.container.removeEventListener("scroll", this.handle_scroll)
    },
    mixins: [back_top()],
    components: {
        Layout,
        BlogDetail,
        BlogToc,
        MessageArea
    },
    data() {
        return {
            data: null,
            comment_data: null,
            is_loading: true,
            is_list_loading: true,
            page: 1,
            active_anchor: "", // 选中的锚点
            text: ""
        }
    },
    computed: {
        blog_id() {
            return this.$route.params.blog_id
        },
        doms() {
            const dom_list = []
            const get_dom = (toc = []) => {
                for (const t of toc) {
                    // 挂载之后才能获取到 dom
                    dom_list.push(document.getElementById(t.anchor))
                    if (t.children && t.children.length) {
                        get_dom(t.children)
                    }
                }
            }
            get_dom(this.data.toc)
            return dom_list
        },
        has_more_comment() {
            return this.comment_data.rows.length < this.comment_data.total
        }
    },
    methods: {
        handle_submit(form_data, callback) {
            request
                .post("/api/comment", {
                    nickname: form_data.nickname,
                    content: form_data.content,
                    blog_id: this.blog_id
                })
                .then((resp) => {
                    this.comment_data.rows.unshift(resp)
                    callback("评论成功！")
                })
        },
        get_anchor() {
            this.active_anchor = ""
            const range = 170
            for (const dom of this.doms) {
                const top = dom.getBoundingClientRect().top
                if (dom) {
                    if (top >= 0 && top < range) {
                        this.active_anchor = dom.id
                        return
                    } else if (top >= range) {
                        return
                    } else {
                        this.active_anchor = dom.id
                    }
                }
            }
        },
        get_more_comment() {
            if (!this.has_more_comment) {
                this.text = "已经到底啦"
                return
            }
            this.page++
            this.is_list_loading = true
            request.get("/api/comment?page=" + this.page).then((resp) => {
                this.comment_data.rows.push(...resp.rows)
                this.is_list_loading = false
            })
        },
        handle_scroll() {
            if (this.is_list_loading) {
                // 上次数据加载完后，才能获取新的数据
                return
            }
            const scroll_height = this.$refs.container.scrollTop,
                container_height =
                    this.$refs.detail.$el.offsetHeight +
                    this.$refs.message.$el.offsetHeight
            if (scroll_height + innerHeight + 100 > container_height) {
                this.get_more_comment()
            }
        }
    }
}
</script>

<style lang="less">
.detail-container {
    text-align: left;
    .main {
        padding: 15px 0 0 20px;
        box-sizing: border-box;
        .container {
            width: 100%;
            height: 100%;
            overflow-y: scroll;
            scroll-behavior: smooth;
        }
    }
    .right {
        width: 200px;
        h2 {
            margin: 15px 0;
            text-align: center;
        }
    }
}
</style>
